package com.smartleanx.module.hrm.service.esign.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.smartleanx.framework.common.pojo.CommonResult;
import com.smartleanx.framework.common.pojo.PageResult;
import com.smartleanx.module.hrm.dal.dataobject.esign.HrmETempDept;
import com.smartleanx.module.hrm.dal.mysql.esign.HrmEContractTempMapper;
import com.smartleanx.module.hrm.dal.mysql.esign.HrmETempDeptMapper;
import com.smartleanx.module.hrm.enums.ErrorCodeConstants;
import com.smartleanx.module.hrm.service.esign.ESignUrlConstant;
import com.smartleanx.module.hrm.service.esign.eums.ActorTypeEnum;
import com.smartleanx.module.hrm.service.esign.eums.CustomComponentsEnum;
import com.smartleanx.module.hrm.service.esign.eums.CustomComponentsTypeEnum;
import com.smartleanx.module.hrm.service.esign.eums.FolderTypeEnum;
import com.smartleanx.module.hrm.service.esign.service.*;
import com.smartleanx.module.hrm.service.esign.temp.param.HrmEContractTempFileParam;
import com.smartleanx.module.hrm.service.esign.temp.param.HrmEContractTempParam;
import com.smartleanx.module.hrm.service.esign.temp.po.*;
import com.smartleanx.module.hrm.service.esign.temp.result.HrmContractCodeResult;
import com.smartleanx.module.hrm.service.esign.temp.result.HrmEContractTempDetailResult;
import com.smartleanx.module.hrm.service.esign.temp.result.HrmEContractTempResult;
import com.smartleanx.module.hrm.service.esign.temp.vo.HrmEContractTempActorsVo;
import com.smartleanx.module.hrm.service.esign.temp.vo.HrmEContractTempVo;
import com.smartleanx.module.hrm.service.examine.util.exception.ResultException;
import com.smartleanx.module.hrm.util.esign.ESignUtil;
import com.smartleanx.module.hrm.util.esign.EsignHttpResponse;
import com.smartleanx.module.hrm.util.esign.enums.EsignRequestType;
import com.smartleanx.module.hrm.util.esign.enums.FileTypeEnums;
import com.smartleanx.module.hrm.util.esign.exception.EsignDemoException;
import com.smartleanx.module.system.api.dept.DeptApi;
import com.smartleanx.module.system.api.dept.dto.DeptRespDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.smartleanx.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * e签报合同模板Service实现
 *
 * @author xzq
 * @since 2025-07-07 15:56:14
 */
@Service
public class HrmEContractTempServiceImpl  extends ServiceImpl<HrmEContractTempMapper, HrmEContractTemp> implements HrmEContractTempService {
    @Value("${esign.url}")
    private String esginUrl;
    @Autowired
    private HrmEContractTempMapper hrmEContractTempMapper;
    @Autowired
    private HrmECustomComponentsService hrmECustomComponentsService;
    @Autowired
    private HrmEFolderTempService hrmEFolderTempService;
    @Autowired
    private HrmETempFileService hrmETempFileService;
    @Autowired
    private HrmEContractTempActorsService hrmEContractTempActorsService;
    @Autowired
    private HrmEContractCodeService hrmEContractCodeService;
    @Autowired
    private HrmETempComponentsService hrmETempComponentsService;
    @Autowired
    private HrmETempDeptMapper hrmETempDeptMapper;

    @Override
    public PageResult<HrmEContractTempResult> getDocTempPage(HrmEContractTempParam param) {
        List<HrmETempDept> hrmETempCorpDeptList = hrmETempDeptMapper.selectList(new LambdaQueryWrapper<>());
        if(CollUtil.isEmpty(hrmETempCorpDeptList)){
            return new PageResult<>(new ArrayList<>(),0L);
        }
        List<Long> tempIds = hrmETempCorpDeptList.stream().map(HrmETempDept::getTempId).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
        if(param.getFolderId() != null){
            List<HrmEFolderTemp> list = hrmEFolderTempService.getFolderListByFolderId(param.getFolderId(),tempIds);
            tempIds = list.stream().map(HrmEFolderTemp::getTempId).collect(Collectors.toList());
            if(CollUtil.isEmpty(tempIds)){
                return new PageResult<>(new ArrayList<>(),0L);
            }
        }



        PageResult<HrmEContractTemp> docTempPage = hrmEContractTempMapper.getDocTempPage(param,tempIds);
        List<HrmEContractTempResult> collect = docTempPage.getList().stream().map(p -> {
            HrmEContractTempResult hrmEContractTempResult = new HrmEContractTempResult();
            BeanUtil.copyProperties(p, hrmEContractTempResult);
            if(p.getCreateTime() != null){
                hrmEContractTempResult.setCreateTime(DateUtil.format(p.getCreateTime(), DatePattern.NORM_DATETIME_PATTERN));
            }
            if(p.getUpdateTime() != null){
                hrmEContractTempResult.setUpdateTime(DateUtil.format(p.getUpdateTime(), DatePattern.NORM_DATETIME_PATTERN));
            }

            return hrmEContractTempResult;
        }).collect(Collectors.toList());

        return new PageResult<>(collect,docTempPage.getTotal());
    }

    @Override
    public HrmEContractTempDetailResult getDocTempDetail(Long id) {
        HrmEContractTempDetailResult hrmEContractTempResult = new HrmEContractTempDetailResult();
        HrmEContractTemp contractTemp = getById(id);
        //1. 模板基础信息
        BeanUtil.copyProperties(contractTemp,hrmEContractTempResult);
        List<String> corpIds = Arrays.asList(contractTemp.getCorpId().split(","));
        List<Long> collect = corpIds.stream().map(Long::new).collect(Collectors.toList());
        hrmEContractTempResult.setCorpId(collect);

        //1.1 模板分组
        List<HrmEFolder> folderList = hrmEFolderTempService.getFolderListByTempId(id);
        List<Long> groupIds = folderList.stream().filter(p -> p.getFolderType().equals(FolderTypeEnum.GROUP.getCode())).map(HrmEFolder::getId).collect(Collectors.toList());
        hrmEContractTempResult.setTempFolderIds(groupIds);
        hrmEContractTempResult.setFolderId(groupIds.get(0));
        //2. 模板文件信息
        List<HrmEFile> fileList = hrmETempFileService.getFileListByTempId(id);
        List<HrmEContractTempFileParam> signFileList = new ArrayList<>();
        List<HrmEContractTempFileParam> attachmentFileList = new ArrayList<>();
        for (HrmEFile hrmEFile : fileList) {
            HrmEContractTempFileParam hrmEContractTempFileParam = new HrmEContractTempFileParam();
            hrmEContractTempFileParam.setFileId(hrmEFile.getEFileId());
            hrmEContractTempFileParam.setFileName(hrmEFile.getFileName());
            hrmEContractTempFileParam.setFileUrl(hrmEFile.getFileUrl());
            if(FileTypeEnums.FILE_SIGN.getType().equals(hrmEFile.getType()+"")){
                signFileList.add(hrmEContractTempFileParam);
            }
            if(FileTypeEnums.FILE_ATTACHMENT.getType().equals(hrmEFile.getType()+"")){
                attachmentFileList.add(hrmEContractTempFileParam);
            }
        }
        hrmEContractTempResult.setSignFileList(signFileList);
        hrmEContractTempResult.setAttachmentFileList(attachmentFileList);
        //3. 模板签署方信息
        List<HrmEContractTempActors> actorsList = hrmEContractTempActorsService.getTempActorsByTempId(id);
        List<HrmEContractTempActorsVo> actorsVoList = actorsList.stream().map(p -> {
            HrmEContractTempActorsVo actorsVo = new HrmEContractTempActorsVo();
            BeanUtil.copyProperties(p, actorsVo);
            return actorsVo;
        }).collect(Collectors.toList());
        hrmEContractTempResult.setActorsList(actorsVoList);


        //4. 编号规则
        if(contractTemp.getExistNumber() == 1){
            List<HrmEContractCode> contractCode = hrmEContractCodeService.getContractCodeBytempId(id);
            List<HrmContractCodeResult> contractCodeList = contractCode.stream().map(p -> {
                HrmContractCodeResult hrmContractCodeResult = new HrmContractCodeResult();
                hrmContractCodeResult.setCode(p.getCode());
                hrmContractCodeResult.setCodeName(p.getName());
                hrmContractCodeResult.setSelected(p.getSelected());
                hrmContractCodeResult.setSortNo(p.getSortNo());
                return hrmContractCodeResult;
            }).collect(Collectors.toList());
            hrmEContractTempResult.setContractCodeList(contractCodeList);
        }

        return hrmEContractTempResult;
    }

    @Override
    public boolean updateDocTempStatus(HrmEContractTempParam param) {
        //1. 如果是要开启 判断当前模板是否有签署控件
        if(param.getTempStatus() == 1){
            HrmEContractTemp hrmEContractTemp = getById(param.getId());
            List<HrmETempComponents> fillInComponents = hrmETempComponentsService.getFillInComponents(hrmEContractTemp.getTempEsignId());
            HrmETempComponents hrmETempComponents = fillInComponents.parallelStream().filter(p -> CustomComponentsTypeEnum.SIGN.getCode().equals(p.getComponentType() + "")).findAny().orElse(null);
            if(ObjUtil.isEmpty(hrmETempComponents)){
                throw exception(ErrorCodeConstants.E_TEMP_SIGN_IS_NULL);
            }
        }

        //2. 修改状态
        update(new LambdaUpdateWrapper<HrmEContractTemp>()
                .eq(HrmEContractTemp::getDataStatus,1)
                .eq(HrmEContractTemp::getId,param.getId())
                .set(HrmEContractTemp::getTempStatus,param.getTempStatus())
        );
        return Boolean.TRUE;
    }

    @Override
    public boolean removeDocTemp(HrmEContractTempParam param) {
        HrmEContractTemp hrmEContractTemp = getById(param.getId());
        if(ObjUtil.isEmpty(hrmEContractTemp)){
            throw exception(ErrorCodeConstants.TEMP_IS_NULL_ERROR);
        }
        hrmEContractTemp.setDataStatus(0);

        updateById(hrmEContractTemp);

        List<HrmEFolderTemp> hrmEFolderList = hrmEFolderTempService.getFolderTempListByTempId(param.getId());
        List<HrmEFolderTemp> updateFolderList = hrmEFolderList.stream().peek(p -> p.setDataStatus(0)).collect(Collectors.toList());
        hrmEFolderTempService.updateBatchById(updateFolderList);

        return Boolean.TRUE;
    }

    @Override
    public JsonObject getDocTempLink(HrmEContractTempVo hrmEContractTempVo) {
        String apiaddr= ESignUrlConstant.TEMP_CREATE_URL;
        //请求方法
        EsignRequestType requestType= EsignRequestType.POST;

        //获取文件id
        String fileId = hrmEContractTempVo.getTempEsignFileId();
        List<HrmEContractTempFileParam> fileList = hrmEContractTempVo.getSignFileList();
        HrmEContractTempFileParam signFile = fileList.get(0);
        String fileName = signFile.getFileName().substring(signFile.getFileName().lastIndexOf('/') + 1);
        String fileType = "doc";
        if(fileName.contains("pdf")){
            fileType = "pdf";
        }


        JSONObject parram = new JSONObject();
        parram.set("docTemplateName",hrmEContractTempVo.getTempName());
        parram.set("docTemplateType",fileType.equals("pdf")?0:1);
//        parram.set("redirectUrl","http://www.baidu.com");
        parram.set("hiddenOriginComponents",false);//是否隐藏原始组件
        parram.set("fileId",fileId);
//        JSONArray customComponentGroups = new JSONArray();
//        customComponentGroups.set("21c5d740f7ac4e0997e9370ce5ea3c87");
//        List<HrmECustomComponents> componentsList = hrmECustomComponentsService.getComponentsFixedList();
//        componentsList.addAll(hrmECustomComponentsService.getComponentsCustomList());
        List<HrmECustomComponents> componentsList = hrmECustomComponentsService.getComponentsCustomList();
        JSONArray customComponents = new JSONArray();
        for (HrmECustomComponents components : componentsList) {
            customComponents.set(components.getComponentId());
        }
        parram.set("customComponents",customComponents);

//        parram.set("customComponentGroups",customComponentGroups);
        JSONArray signerRoles = new JSONArray();
        List<HrmEContractTempActorsVo> actorsList = hrmEContractTempVo.getActorsList();
        for (HrmEContractTempActorsVo actorsVo : actorsList) {
            if(0 == actorsVo.getActorSignPermission()){
                continue;
            }
            if(Integer.parseInt(ActorTypeEnum.CORP.getCode()) == actorsVo.getActorType()){
                signerRoles.put(ActorTypeEnum.CORP.getDesc());
            }else if (Integer.parseInt(ActorTypeEnum.PERSON.getCode()) == actorsVo.getActorType()){
                signerRoles.put(ActorTypeEnum.PERSON.getDesc());
            }
        }
        parram.set("signerRoles",signerRoles);
        String jsonParm=parram.toString();


        try {
            EsignHttpResponse esignHttpResponse = ESignUtil.sendHttpResponse(jsonParm, requestType, apiaddr, esginUrl);
            Gson gson = new Gson();
            JsonObject getUploadUrlJsonObject = gson.fromJson(esignHttpResponse.getBody(), JsonObject.class);
            JsonObject data = getUploadUrlJsonObject.getAsJsonObject("data");


            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public JsonObject getDocTempEditLink(HrmEContractTempVo hrmEContractTempVo) {
        String apiaddr= String.format(ESignUrlConstant.TEMP_EDIT_URL,hrmEContractTempVo.getTempEsignId());
        //请求方法
        EsignRequestType requestType= EsignRequestType.POST;


        JSONObject parram = new JSONObject();
        parram.set("hiddenOriginComponents",false);//是否隐藏原始组件
//        JSONArray customComponentGroups = new JSONArray();
//        customComponentGroups.set("21c5d740f7ac4e0997e9370ce5ea3c87");
        List<HrmECustomComponents> componentsList = hrmECustomComponentsService.getComponentsList();
        JSONArray customComponents = new JSONArray();
        for (HrmECustomComponents components : componentsList) {
            customComponents.set(components.getComponentId());
        }
        parram.set("customComponents",customComponents);

//        parram.set("customComponentGroups",customComponentGroups);
        JSONArray signerRoles = new JSONArray();
        List<HrmEContractTempActorsVo> actorsList = hrmEContractTempVo.getActorsList();
        for (HrmEContractTempActorsVo actorsVo : actorsList) {
            if(0 == actorsVo.getActorSignPermission()){
                continue;
            }
            if(Integer.parseInt(ActorTypeEnum.CORP.getCode()) == actorsVo.getActorType()){
                signerRoles.put(ActorTypeEnum.CORP.getDesc());
            }else if (Integer.parseInt(ActorTypeEnum.PERSON.getCode()) == actorsVo.getActorType()){
                signerRoles.put(ActorTypeEnum.PERSON.getDesc());
            }
        }
        parram.set("signerRoles",signerRoles);
        String jsonParm=parram.toString();


        try {
            EsignHttpResponse esignHttpResponse = ESignUtil.sendHttpResponse(jsonParm, requestType, apiaddr, esginUrl);
            Gson gson = new Gson();
            JsonObject getUploadUrlJsonObject = gson.fromJson(esignHttpResponse.getBody(), JsonObject.class);
            JsonObject data = getUploadUrlJsonObject.getAsJsonObject("data");


            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public HrmEContractTemp getDocTempBySignId(String tempSignId) {
        return hrmEContractTempMapper.selectOne(new LambdaQueryWrapper<HrmEContractTemp>()
        .eq(HrmEContractTemp::getTempEsignId,tempSignId));
    }
}
